﻿using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.GraphicsSystem;
using System;

namespace NFox.Cad.Runtime
{

    public static class SystemManager
    {

        #region Goal

        public static Database CurrentDatabase
        {
            get
            {
                return HostApplicationServices.WorkingDatabase;
            }
        }

        public static Document ActiveDocument
        {
            get
            {
                return Application.DocumentManager.MdiActiveDocument;
            }
        }

        public static Editor Editor
        {
            get
            {
                return ActiveDocument.Editor;
            }
        }

        public static Manager GsManager
        {
            get
            {
                return ActiveDocument.GraphicsManager;
            }
        }

        #endregion

        #region Preferences

        public static object GetCurrentProfileProperty(string subSectionName, string propertyName)
        {
            UserConfigurationManager ucm = Application.UserConfigurationManager;
            IConfigurationSection cpf = ucm.OpenCurrentProfile();
            IConfigurationSection ss = cpf.OpenSubsection(subSectionName);
            return ss.ReadProperty(propertyName, "");
        }

        public static IConfigurationSection GetDialogSection(object dialog, string propertyName)
        {
            UserConfigurationManager ucm = Application.UserConfigurationManager;
            IConfigurationSection ds = ucm.OpenDialogSection(dialog);
            return ds;
        }

        public static IConfigurationSection GetGlobalSection(string propertyName)
        {
            UserConfigurationManager ucm = Application.UserConfigurationManager;
            IConfigurationSection gs = ucm.OpenGlobalSection();
            IConfigurationSection ss = gs.OpenSubsection(propertyName);
            return ss;
        }

        #endregion

        #region Enum

        private static T ToEnum<T>(this string value)
        {
            return (T)Enum.Parse(typeof(T), value, true);
        }

        private static string GetName<T>(this T value)
        {
            return Enum.GetName(typeof(T), value);
        }
        
        #region Dimblk

        public enum DimblkType
        {
            Defult,
            Dot,
            DotSmall,
            DotBlank,
            Origin,
            Origin2,
            Open,
            Open90,
            Open30,
            Closed,
            Small,
            None,
            Oblique,
            BoxFilled,
            BoxBlank,
            ClosedBlank,
            DatumFilled,
            DatumBlank,
            Integral,
            ArchTick,
        }

        public static DimblkType Dimblk
        {
            get
            {
                string s = (string)Application.GetSystemVariable("dimblk");
                if (s == "" || s == null)
                {
                    return DimblkType.Defult;
                }
                else
                {
                    return s.ToEnum<DimblkType>();
                }
            }
            set
            {
                string s = GetDimblkName(value);
                Application.SetSystemVariable("dimblk", s);
            }
        }

        public static string GetDimblkName(DimblkType dimblk)
        {
            return
                dimblk == DimblkType.Defult 
                ?
                "." 
                : 
                "_" + dimblk.GetName();

        }

        public static ObjectId GetDimblkId(DimblkType dimblk)
        {
            DimblkType oldDimblk = Dimblk;
            Dimblk = dimblk;
            ObjectId id = HostApplicationServices.WorkingDatabase.Dimblk;
            Dimblk = oldDimblk;
            return id;
        }

        #endregion

        #region OsMode

        public enum OSModeType
        {
            None = 0,
            End = 1,
            Middle = 2,
            Center = 4,
            Node = 8,
            Quadrant = 16,
            Intersection = 32,
            Insert = 64,
            Pedal = 128,
            Tangent = 256,
            Nearest = 512,
            Quick = 1024,
            Appearance = 2048,
            Extension = 4096,
            Parallel = 8192
        }

        public static OSModeType OSMode
        {
            get
            {
                return (OSModeType)Convert.ToInt16(Application.GetSystemVariable("osmode"));
            }
            set
            {
                Application.SetSystemVariable("osmode", (int)value);
            }
        }


        public static void Append(this OSModeType osm1, OSModeType osm2)
        {
            osm1 |= osm2;
        }

        public static bool Check(this OSModeType osm1, OSModeType osm2)
        {
            return (osm1 & osm2) == osm2;
        }

        public static void Remove(this OSModeType osm1, OSModeType osm2)
        {
            osm1 ^= osm2;
        }

        #endregion

        public static bool CmdEcho
        {
            get
            {
                return (int)Application.GetSystemVariable("cmdecho") == 1;
            }
            set
            {
                Application.SetSystemVariable("cmdecho", Convert.ToInt16(value));
            }
        }

        #endregion

    }
}
